/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package carreras.entidades;

import carreras.Configuracion;
import carreras.logger.CarrerasLogger;
import carreras.negocio.NegCarrera;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 *
 * @author Fanky10 <fanky10@gmail.com>
 */
public abstract class Carrera extends ArrayList<CarrilCarrera> {
    private int id;
    private static final int CANT_DE_CARRILES = Configuracion.getInstance().getCant_carriles(); //configurable externamente
    
    public Carrera(){
        super();
    }
    /**
     * 
     * @return true si esta completa, false caso contrario
     */
    public boolean isCompleta(){
        if(this.size()>=CANT_DE_CARRILES){
            return true;
        }
        return false;
    }
    /**
     * 
     * @param cc
     * @return true si todo ok false caso contrario 
     */
    public boolean add(CarrilCarrera cc){
        if(isCompleta())
            throw new IllegalArgumentException("esto completo, si esto sucede muy amenudo.. lo mejor es evitarlo xD");
        return super.add(cc);
    }
    public boolean add(CorredorAuto ca){
        int nro_carril = 1;
        for(CarrilCarrera cc: this){
            nro_carril++;
        }
        return add(new CarrilCarrera(ca, nro_carril));
    }
    //TODO: ver que onda
    public boolean isCarreraOver(){
        for(CarrilCarrera cc: this){
            if(!cc.isEsta_actualizado()){//si al menos uno no esta actualizado todo mal
                CarrerasLogger.debug(Carrera.class,cc.getAuto()+" no esta actualizada loco!");
                return false;
            }
        }
        //si no hay ninguno sin actualizar...
        return true;
    }
    //si termino es logico pensar que es necesario devolverle el ganador!!
    public CarrilCarrera getGanador(){
        if(this.isEmpty()){
            throw new IllegalArgumentException("que oonda! no hay nadie para quien buscar :P");
        }
        if(this.size()==1){
            return this.get(0);
        }
        for(CarrilCarrera cc: this){
            if(cc.getEstado_carrera() == CarrilCarrera.ESTADO_GANADOR){
                return cc;
            }
        }
        throw new IllegalArgumentException("que oonda! no hubo ganadores??");
    }
    public void actualizaTiempos(arduino.entidades.Carril carril) throws SQLException{
        CarrilCarrera c = getCarril(carril.getNro_carril());
        c.actualiza_tiempos(carril.getTiempoV());
        //TODO: insertar en db
        new NegCarrera().addCarrilCarrera(c, this);
        if(isCarreraOver()){//decido quien es el ganador y quien el perdedor
            CarrerasLogger.debug(Carrera.class, "carrera is over, vamos a actualizar estados!");
            actualiza_estados();
        }
    }
    /**
     * decide quien gano y quien perdio xD
     */
    private void actualiza_estados(){
        Collections.sort(this, new Comparator<CarrilCarrera>(){

            @Override
            public int compare(CarrilCarrera cc, CarrilCarrera cci) {
                if(cci.getTiempos().getTiempoDecisorio().getTiempo()>0 && 
                            cc.getTiempos().getTiempoDecisorio().getTiempo()>cci.getTiempos().getTiempoDecisorio().getTiempo()){
                    return 1;
                }else if(cci.getTiempos().getTiempoDecisorio().getTiempo()>0 && 
                            cc.getTiempos().getTiempoDecisorio().getTiempo()<cci.getTiempos().getTiempoDecisorio().getTiempo()){
                    return -1;
                }else{
                    return 0;
                }
            }
        
        });
        for(int i = 0;i<this.size();i++){
            CarrilCarrera cc = this.get(i);
            if(i==0){
                cc.setEstado_carrera(CarrilCarrera.ESTADO_GANADOR);
                
            }//chequeo que este esperando datos y que no este roto y eso
            else if(cc.getEstado_carrera() == CarrilCarrera.ESTADO_ESPERANDO_DATOS
                        || cc.getEstado_carrera() == CarrilCarrera.ESTADO_SIN_DATOS){
                
                cc.setEstado_carrera(CarrilCarrera.ESTADO_PERDEDOR);
            }
        }
    }
    public CarrilCarrera getCarril(int nro_carril){
        for(CarrilCarrera c: this){
            if(c.getNro_carril()==nro_carril){
//                CarrerasLogger.debug(Carrera.class, "devolviendo carril: "+c);
                return c;
            }
        }
        throw new IllegalArgumentException("Carrera no encontrada en carril nro: "+nro_carril);
    }
    /**
     * actualiza todos el estado de todos los carriles, se usa para inicializar algo
     * @param estado_carrera 
     */
    public void setEstado_carrera(int estado_carrera){
        for(CarrilCarrera c: this){
            c.setEstado_carrera(estado_carrera);
        }
    }
    public Categoria getCategoria(){
        if(this.isEmpty()){
            throw new IllegalArgumentException("no puedo devolver que cat. si no tengo elementos");
        }
        return this.get(0).getCorredor_auto().getCategoria();
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
    
    public abstract CatCorredorAuto getCatCorredorAuto();
    public abstract void eliminaPerdedor();
}
